package com.csu.express.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.csu.common.exception.WebException;
import com.csu.common.utils.BeanUtil;
import com.csu.common.utils.PasswdUtil;
import com.csu.express.cache.DriverCacheService;
import com.csu.express.constants.ErrorCode;
import com.csu.express.dao.DriverMapper;
import com.csu.express.dao.DriverVehicleMapper;
import com.csu.express.dao.VehicleMapper;
import com.csu.express.pojo.DriverLocationPojo;
import com.csu.express.pojo.DriverPojo;
import com.csu.express.pojo.DriverVehiclePojo;
import com.csu.express.pojo.VehiclePojo;
import com.csu.express.service.DriverService;
import com.csu.express.vo.DriverVo;

/**
 * @项目名称：express
 * @类名称：DriverServiceImpl
 * @类描述：
 * @创建人：Tangc
 * @创建时间：2017年9月22日 上午10:11:26
 * @company:
 */
@Service
public class DriverServiceImpl implements DriverService
{
    private static final Logger logger = Logger.getLogger(DriverServiceImpl.class);

    @Autowired
    private DriverMapper driverMapper;

    @Autowired
    private DriverVehicleMapper driverVehicleMapper;

    @Autowired
    private VehicleMapper vehicleMapper;

    @Autowired
    private DriverCacheService driverCacheService;

    /**
     * @throws WebException
     * @see com.csu.express.service.DriverService#login(java.lang.String,
     *      java.lang.String)
     */
    @Override
    public DriverPojo login(String cellPhone, String password) throws WebException
    {
        DriverPojo driver = driverMapper.selectByCellPhone(cellPhone);

        if (driver == null)
        {
            throw new WebException(ErrorCode.UserNullCode, ErrorCode.UserNullMessgae);
        }
        if (!PasswdUtil.checkPasswd(password, driver.getSalt(), driver.getPasswd()))
        {
            throw new WebException(ErrorCode.PasswdErrorCode, ErrorCode.PasswdErrorMessgae);
        }

        return driver;
    }

    /** 
     * @see com.csu.express.service.DriverService#getDriverById(java.lang.String)
     */
    @Override
    public DriverPojo getDriverById(String driverId)
    {

        return null;
    }

    @Override
    public DriverVo getDriverInfoBySn(String driverSn) throws WebException
    {
        DriverVo result = null;

        DriverPojo driverPojo = driverMapper.selectBySn(driverSn);
        if (driverPojo == null)
        {
            logger.error("driverSn:" + driverSn + "找不到司机信息");
            throw new WebException(ErrorCode.SourceNotExistCode, ErrorCode.SourceNotExistMessage);
        }

        DriverVehiclePojo driverVehiclePojo = driverVehicleMapper.selectByDriverSn(driverSn);
        if (driverVehiclePojo == null)
        {
            logger.error("driverSn:" + driverSn + "找不到司机提供服务的车辆");
            throw new WebException(ErrorCode.SourceNotExistCode, ErrorCode.SourceNotExistMessage);
        }

        VehiclePojo vehiclePojo = vehicleMapper.selectByVehicleNumber(driverVehiclePojo.getVehicleNumber());
        if (vehiclePojo == null)
        {
            logger.error("vehicleNumber:" + driverVehiclePojo.getVehicleNumber() + "找不到车辆信息");
            throw new WebException(ErrorCode.SourceNotExistCode, ErrorCode.SourceNotExistMessage);
        }

        result = new DriverVo();
        BeanUtil.copyNotNullProperties(result, driverPojo);
        BeanUtil.copyNotNullProperties(result, vehiclePojo);
        result.setDriverSn(driverPojo.getSerialNumber());

        return result;
    }

    @Override
    public List<DriverVo> getDriverInfosBySns(List<String> driverSns) throws WebException
    {
        List<DriverVo> result = null;

        List<DriverPojo> driverPojos = driverMapper.selectBySns(driverSns);
        if (driverPojos == null || driverPojos.isEmpty())
        {
            logger.error("找不到司机们的信息");
            throw new WebException(ErrorCode.SourceNotExistCode, ErrorCode.SourceNotExistMessage);
        }

        List<DriverVehiclePojo> driverVehiclePojos = driverVehicleMapper.selectByDriverSns(driverSns);
        if (driverVehiclePojos == null || driverVehiclePojos.isEmpty())
        {
            logger.error("找不到司机们提供服务的车辆");
            throw new WebException(ErrorCode.SourceNotExistCode, ErrorCode.SourceNotExistMessage);
        }

        List<String> vehicleNumbers = getVehicleNumbers(driverVehiclePojos);

        List<VehiclePojo> vehiclePojos = vehicleMapper.selectByVehicleNumbers(vehicleNumbers);
        if (vehiclePojos == null || vehiclePojos.isEmpty())
        {
            logger.error("找不到车辆信息");
            throw new WebException(ErrorCode.SourceNotExistCode, ErrorCode.SourceNotExistMessage);
        }

        Map<String, VehiclePojo> driverVehicleMap = new HashMap<>();
        generateDriverVehicleMap(driverVehiclePojos, vehiclePojos, driverVehicleMap);

        result = new ArrayList<>();
        for (DriverPojo driverPojo : driverPojos)
        {
            DriverVo driverVo = new DriverVo();
            BeanUtil.copyNotNullProperties(driverVo, driverPojo);
            driverVo.setDriverSn(driverPojo.getSerialNumber());

            VehiclePojo vehiclePojo = driverVehicleMap.get(driverPojo.getSerialNumber());
            BeanUtil.copyNotNullProperties(driverVo, vehiclePojo);
            result.add(driverVo);
        }

        return result;
    }

    private List<String> getVehicleNumbers(List<DriverVehiclePojo> driverVehiclePojos)
    {
        List<String> result = new ArrayList<>();
        for (DriverVehiclePojo driverVehiclePojo : driverVehiclePojos)
        {
            result.add(driverVehiclePojo.getVehicleNumber());
        }

        return result;
    }

    private void generateDriverVehicleMap(List<DriverVehiclePojo> driverVehiclePojos, List<VehiclePojo> vehiclePojos,
            Map<String, VehiclePojo> driverVehicleMap)
    {
        for (DriverVehiclePojo driverVehiclePojo : driverVehiclePojos)
        {
            String driverSn = driverVehiclePojo.getDriverSn();
            for (VehiclePojo vehiclePojo : vehiclePojos)
            {
                if (driverVehiclePojo.getVehicleNumber().equals(vehiclePojo.getVehicleNumber()))
                {
                    driverVehicleMap.put(driverSn, vehiclePojo);
                }
            }
        }
    }

    @Override
    public void updateLocation(DriverLocationPojo driverLocationPojo) throws WebException
    {
        // 将最新的位置信息更新到缓存
        driverCacheService.addDriverLocationToCache(driverLocationPojo);

        // try
        // {
        // // 将位置信息插入表中，允许插入失败，后续可以升级为用异步队列去做
        // driverLocationPojo.setCreateTime(new Date());
        // driverLocationMapper.add(driverLocationPojo);
        // }
        // catch (Exception e)
        // {
        // // 不做处理
        // }
    }

    @Override
    public DriverLocationPojo getDriverLocation(String driverSn) throws WebException
    {
        return driverCacheService.getDriverLocationFromCache(driverSn);
    }

    @Override
    public int updateServiceInfo(DriverVo driverVo)
    {
        return driverMapper.updateServiceInfo(driverVo);
    }
}
